package com.ld.security.config;

import com.ld.vaadin.view.IndexView;
import com.vaadin.flow.spring.security.VaadinWebSecurity;
import lombok.RequiredArgsConstructor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

/**
 * DelegatingFilterProxy 作用：
 * 实现把Servlet容器中的 Filter 同 Spring 容器中的 bean 关联起来，
 * DelegatingFilterProxy实现了Filter接口，Servlet容器启动就会加载好这个类。
 * 借助他可以实现普通的Filter拦截到的Http请求交由FilterChainProxy。
 * <p>
 * <p>
 * <p>
 * DelegatingFilterProxy：Servlet过滤器入口，委托给Spring的 FilterChainProxy。
 * <p>
 * FilterChainProxy：Spring安全核心，管理多个 SecurityFilterChain 并选择执行。
 * <p>
 * SecurityFilterChain：安全规则的最小单元，定义URL匹配条件和过滤器集合。
 * <p>
 * <p>
 * security 所有的默认过滤器
 * DisableEncodeUrlFilter
 * WebAsyncManagerIntegrationFilter
 * SecurityContextHolderFilter
 * HeaderWriterFilter
 * LogoutFilter
 * JwtAuthenticationFilter
 * RequestCacheAwareFilter
 * SecurityContextHolderAwareRequestFilter
 * AnonymousAuthenticationFilter
 * SessionManagementFilter
 * ExceptionTranslationFilter
 * AuthorizationFilter
 */
@Configuration
@EnableWebSecurity(debug = false)
@RequiredArgsConstructor
public class SecurityConfig extends VaadinWebSecurity {

    private final JwtAuthenticationFilter jwtAuthFilter;
    private final AuthenticationProvider authenticationProvider;

//    @Bean
//    public SecurityFilterChain securityFilterChain(HttpSecurity httpSecurity) throws Exception {
//        httpSecurity.csrf(AbstractHttpConfigurer::disable)
//                .authorizeHttpRequests(
//                        authorizationManagerRequestMatcherRegistry
//                                -> authorizationManagerRequestMatcherRegistry
//                                .requestMatchers(
//                                        "/",
//                                        "/register",
//                                        "/VAADIN/**",
//                                        "favicon.ico",
//                                        "/api/v1/auth/**"
//                                )
////                                以上请求不拦截
//                                .permitAll()
////                                其它所有请求必须经过认证
//                                .anyRequest().authenticated())
////                禁用session，采用无状态
//                .sessionManagement(
//                        httpSecuritySessionManagementConfigurer
//                                -> httpSecuritySessionManagementConfigurer
//                                .sessionCreationPolicy(SessionCreationPolicy.STATELESS))
////                身份验证程序设置
//                .authenticationProvider(authenticationProvider)
////                添加自定义过滤器-(在UsernamePasswordAuthenticationFilter过滤器之前添加)
//                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
//                .exceptionHandling(h -> System.out.println("异常"))
//        return httpSecurity.build();
//    }

    // 高优先级：匹配 /api/** 的请求
    @Bean
    @Order(1)
    public SecurityFilterChain apiFilterChain(HttpSecurity http) throws Exception {
        http
                .securityMatcher("/api/json/**")
                .authorizeHttpRequests(auth -> auth
                        .requestMatchers("/api/json/v1/auth/**")
                        .permitAll()
                        .anyRequest()
                        .authenticated())
                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
                .authenticationProvider(authenticationProvider)//身份验证程序设置
                .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class)
                .formLogin(AbstractHttpConfigurer::disable)
                .csrf(AbstractHttpConfigurer::disable);
        return http.build();
    }

    // 中优先级：处理 /admin/** 路径的请求（表单登录）
//    @Bean
//    @Order(2)
//    public SecurityFilterChain formFilterChain(HttpSecurity http) throws Exception {
//        http
//                .securityMatcher("/api/form/**")
//                .authorizeHttpRequests(auth -> auth
//                        .requestMatchers("/api/form/v1/user/**")
//                        .permitAll()
//                        .anyRequest()
//                        .authenticated()
//                )
//                .formLogin(form -> form
//                        .usernameParameter("email")
//                        .passwordParameter("credentials")
//                        .defaultSuccessUrl("/page/home", true)
////                        .failureForwardUrl("/")
//                        .permitAll()
//                )
//                .csrf(AbstractHttpConfigurer::disable)
//                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
//
//        return http.build();
//    }

    // 中优先级：处理 /admin/** 路径的请求（表单登录）
//    @Bean
//    @Order(3)
//    public SecurityFilterChain pageFilterChain(HttpSecurity http) throws Exception {
//        http
//                .securityMatcher("/page/**")
//                .authorizeHttpRequests(auth -> auth
//                        .anyRequest()
//                        .authenticated()
//                )
//                .csrf(AbstractHttpConfigurer::disable)
//                .sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
//
//        return http.build();
//    }

    // 低优先级：处理其他所有请求（默认放行）
//    @Bean
//    @Order(4)
//    public SecurityFilterChain defaultFilterChain(HttpSecurity http) throws Exception {
//        http
//                .securityMatcher("**") // 匹配所有剩余请求
//                .authorizeHttpRequests(auth -> auth
//                        .anyRequest().permitAll() // 允许匿名访问
//                )
//                .csrf(AbstractHttpConfigurer::disable);
//
//        return http.build();
//    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
//        form表单登录的需要session管理，因为页面在系统内部，没法向vue一样单独管理，父子工程可以考虑分开去掉session
//        http.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS));
        http.formLogin(form -> form.loginPage("/login"));
        super.configure(http);
        setLoginView(http, IndexView.class);
    }

}
